home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_05
/
1005010a
< prev
next >
Wrap
Text File
|
1992-03-04
|
2KB
|
84 lines
Listing 1 -- xstoul.c
/* _Stoul function */
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <string.h>
/* macros */
#define BASE_MAX 36 /* largest valid base */
/* static data */
static const char digits[] = { /* valid digits */
"0123456789abcdefghijklmnopqrstuvwxyz"};
static const char ndigs[BASE_MAX+1] = { /* 32-bits! */
0, 0, 33, 21, 17, 14, 13, 12, 11, 11,
10, 10, 9, 9, 9, 9, 9, 8, 8, 8,
8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7,};
unsigned long _Stoul(const char *s, char **endptr, int base)
{ /* convert string to unsigned long, with checking */
const char *sc, *sd;
const char *s1, *s2;
char sign;
ptrdiff_t n;
unsigned long x, y;
for (sc = s; isspace(*sc); ++sc)
;
sign = *sc == '-' || *sc == '+' ? *sc++ : '+';
if (base < 0 || base == 1 || BASE_MAX < base)
{ /* silly base */
if (endptr)
*endptr = (char *)s;
return (0);
}
else if (base)
{ /* strip 0x or 0X */
if (base == 16 && *sc == '0'
&& (sc[1] == 'x' || sc[1] == 'X'))
sc += 2;
}
else if (*sc != '0')
base = 10;
else if (sc[1] == 'x' || sc[1] == 'X')
base = 16, sc += 2;
else
base = 8;
for (s1 = sc; *sc == '0'; ++sc)
; /* skip leading zeros */
x = 0;
for (s2 = sc; (sd = (char *)memchr(digits,
tolower(*sc), base)) != NULL; ++sc)
{ /* accumulate digits */
y = x; /* for overflow checking */
x = x * base + (sd - digits);
}
if (s1 == sc)
{ /* check string validity */
if (endptr)
*endptr = (char *)s;
return (0);
}
n = sc - s2 - ndigs[base];
if (n < 0)
;
else if (0 < n || x < x - sc[-1]
|| (x - sc[-1]) / base != y)
{ /* overflow */
errno = ERANGE;
x = ULONG_MAX;
}
if (sign == '-') /* get final value */
x = -x;
if (endptr)
*endptr = (char *)sc;
return (x);
}